home *** CD-ROM | disk | FTP | other *** search
- /*
- * gpm-xterm.c - pseudo client for non-Linux xterm only mouse support.
- * This code has been extracted from libgpm-0.18 and then
- * took its own way.
- *
- * Copyright (C) 1994 rubini@ipvvis.unipv.it (Alessandro Rubini)
- * Copyright (C) 1994 Janne Kukonlehto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ********/
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h> /* select(); */
- #include <sys/time.h> /* timeval */
- #include <sys/types.h> /* socket() */
-
- #ifdef HAVE_NCURSES_H
- #include <ncurses.h>
- #else
- #include <curses.h>
- #endif
-
- #include "gpm-xterm.h"
- #define RELEASE "0.97"
-
- /******* This from liblow.c(libgpm) */
-
- int gpm_flag = 0, gpm_tried = 0, gpm_fd = -1, gpm_hflag = 0;
- int gpm_zerobased = 0, gpm_visiblepointer = 0, gpm_morekeys = 0;
- struct timeval gpm_timeout =
- {10, 0};
-
- Gpm_Handler *gpm_handler = NULL;
- void *gpm_data = NULL;
-
- static int gpm_convert_event (char *mdata, Gpm_Event * ePtr);
-
- /******* This from libcurses.c(libgpm) */
- int
- Gpm_Wgetch (WINDOW * win)
- {
- int flag, result;
- int fd = STDIN_FILENO;
- static Gpm_Event ev;
- static struct timeval to =
- {0, 0}, tv1 =
- {0, 0}, tv2;
- static fd_set selSet;
- static int prevchar = EOF, clicks = 0;
- static char mdata[4];
- int c;
-
- #define GET(win) ((win) ? wgetch(win) : getch())
-
- #define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL))
- #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \
- (t2.tv_usec-t1.tv_usec)/1000)
-
- if (!gpm_flag)
- return GET (win);
- if (gpm_morekeys && gpm_handler)
- return (*gpm_handler) (&ev, gpm_data);
-
- gpm_hflag = 0; /* not generated by handler (default) */
-
- if ((c = prevchar) != EOF) { /* if ungetc() didn't suffice... */
- prevchar = EOF;
- return c;
- }
- while (1) {
- do {
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- gpm_timeout.tv_sec = SELECT_TIME;
- flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to);
- }
- while (!flag);
-
- if ((c = GET (win)) != 0x1b)
- return c;
-
- /* escape: go on */
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0)
- return c;
- if ((c = GET (win)) != '[') {
- ungetc (c, stdin);
- return 0x1B;
- }
- /* '[': go on */
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0) {
- ungetc (c, stdin);
- return 0x1B;
- }
- if ((c = GET (win)) != 'M') {
- ungetc (c, stdin);
- prevchar = '[';
- return 0x1B;
- }
- /* now, it surely is a mouse event */
- for (c = 0; c < 3; c++)
- mdata[c] = GET (win);
- gpm_convert_event (mdata, &ev);
-
- if (gpm_handler && (result = (*gpm_handler) (&ev, gpm_data))) {
- gpm_hflag = 1;
- return result;
- }
- } /* while(1) */
- }
-
- /******* This from liblow.c(libgpm) */
- int
- Gpm_Open (Gpm_Connect * conn, int flag)
- {
- char *tty;
- int i;
-
- if ((tty = (char *) getenv ("TERM")) && !strncmp (tty, "xterm", 5)) {
- if (gpm_tried)
- return gpm_fd; /* already open */
- gpm_fd = -2;
- GPM_XTERM_ON;
- gpm_flag = 1;
- return gpm_fd;
- }
- return -1;
- }
-
- int
- Gpm_Close (void)
- {
- if (gpm_fd == -2) /* xterm */
- GPM_XTERM_OFF;
- gpm_tried = 0;
- gpm_fd = -1;
- return 0;
- }
-
- int
- Gpm_Getc (FILE * f)
- {
- #define DELAY_MS 500 /* stolen form mc */
- int flag, result;
- static Gpm_Event ev;
- int fd = fileno (f);
- static int count;
- static struct timeval to =
- {0, DELAY_MS * 1000}, tv1 =
- {0, 0}, tv2;
- static fd_set selSet;
- static int prevchar = EOF, clicks = 0;
- static char mdata[4];
- int c;
-
- /* Hmm... I must be sure it is unbuffered */
- if (!(count++))
- setvbuf (f, NULL, _IONBF, 0);
-
- if (!gpm_flag)
- return fgetc (f);
-
- /* If the handler asked to provide more keys, give them back */
- if (gpm_morekeys && gpm_handler)
- return (*gpm_handler) (&ev, gpm_data);
- gpm_hflag = 0;
-
- if ((c = prevchar) != EOF) { /* if ungetc() didn't suffice... */
- prevchar = EOF;
- return c;
- }
- while (1) {
- do {
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- gpm_timeout.tv_sec = SELECT_TIME;
- flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to);
- }
- while (!flag);
-
- if ((c = fgetc (f)) != 0x1b)
- return c;
-
- /* escape: go on */
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- to.tv_usec = DELAY_MS * 1000;
- if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0)
- return c;
- if ((c = fgetc (f)) != '[') {
- ungetc (c, stdin);
- return 0x1B;
- }
- /* '[': go on */
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- to.tv_usec = DELAY_MS * 1000;
- if ((flag = select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to)) == 0) {
- ungetc (c, f);
- return 0x1B;
- }
- if ((c = fgetc (f)) != 'M') {
- ungetc (c, f);
- prevchar = '[';
- return 0x1B;
- }
- /* now, it surely is a mouse event */
- for (c = 0; c < 3; c++)
- mdata[c] = fgetc (f);
- gpm_convert_event (mdata, &ev);
-
- if (gpm_handler && (result = (*gpm_handler) (&ev, gpm_data))) {
- gpm_hflag = 1;
- return result;
- }
- } /* while(1) */
- }
-
- int
- Gpm_Repeat (int msec)
- {
- struct timeval to =
- {0, 0};
- fd_set selSet;
- int fd = STDIN_FILENO;
-
- to.tv_usec = msec * 1000;
- FD_ZERO (&selSet);
- FD_SET (fd, &selSet);
- return (select (fd + 1, &selSet, (fd_set *) NULL, (fd_set *) NULL, &to) == 0);
- }
-
- /*-------------------------------------------------------------------*/
- /* this is the real protocol conversion */
- static int
- gpm_convert_event (char *mdata, Gpm_Event * ePtr)
- {
- static struct timeval tv1 =
- {0, 0}, tv2;
- static int clicks = 0;
- int c;
-
- #define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL))
- #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \
- (t2.tv_usec-t1.tv_usec)/1000)
-
-
- /* Variable btn has following meaning: */
- c = mdata[0] - 32; /* 0="1-down", 1="2-down", 2="3-down", 3="up" */
-
- if (c == 3) {
- ePtr->type = GPM_UP | (GPM_SINGLE << clicks);
- ePtr->buttons = 0;
- GET_TIME (tv1);
- clicks = 0;
- } else {
- ePtr->type = GPM_DOWN;
- GET_TIME (tv2);
- if (tv1.tv_sec && (DIF_TIME (tv1, tv2) < 250)) { /* 250ms for double click */
- clicks++;
- clicks %= 3;
- } else
- clicks = 0;
-
- switch (c) {
- case 0:
- ePtr->buttons |= GPM_B_LEFT;
- break;
- case 1:
- ePtr->buttons |= GPM_B_MIDDLE;
- break;
- case 2:
- ePtr->buttons |= GPM_B_RIGHT;
- break;
- default: /* Nothing */
- break;
- }
- }
- /* Coordinates are 33-based */
- /* Transform them to 1-based */
- ePtr->x = mdata[1] - 32;
- ePtr->y = mdata[2] - 32;
- return 0;
- }
-